package com.wang.zgkj.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * @author WangXinzhu
 * @date 2022/12/8 22:18
 * @since 1.0
 */
@Service
public class UpdateService {
    List<FileProtocol> fileProtocolList = new ArrayList<>();

    public static ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 将原始文件夹读取并合并写入到新的一个文件
     *
     * @return 返回生产的新文件路径
     * @throws IOException
     */
    public String readAndRewrite() throws IOException {
        Resource resource = new ClassPathResource("update");
        //获1.txt的取相对路径
        recursionRead(resource.getFile());
        Path source = Paths.get(resource.getFile().getParentFile().getAbsolutePath());
        Path recovery = Paths.get(source.toAbsolutePath() + "/recovery");
        Path directories = Files.createDirectories(recovery);
        Path binFile = Files.createFile(Paths.get(directories.toAbsolutePath() + "/" + System.currentTimeMillis() + ".file"));
        byte[] bytes = objectMapper.writeValueAsBytes(fileProtocolList);
        Files.write(binFile, bytes);
        return binFile.toString();

    }

    /**
     * 递归读取文件夹
     *
     * @param file
     * @throws IOException
     */
    public void recursionRead(File file) throws IOException {
        if (file.isFile()) {
            System.out.println(file.getPath());
            byte[] body = getBody(file);
            fileProtocolList.add(FileProtocol.builder().fileName(file.getName()).filePath(getPath(file)).isFile("true").body(body).len(body.length).build());
        } else {
            fileProtocolList.add(FileProtocol.builder().fileName(file.getName()).filePath(getPath(file)).isFile("false").build());

            File[] files = file.listFiles();
            for (File f : files) {
                recursionRead(f);
            }
        }


    }

    private String getPath(File file) {
        return getParentPath(file);
    }

    private String getParentPath(File file) {
        boolean isRoot = file.isDirectory() && file.getName().equals("update");
        if (isRoot) {
            return "/" + file.getName();
        } else {
            return getParentPath(file.getParentFile()) + "/" + file.getName();
        }
    }

    private byte[] getBody(File file) throws IOException {
        return file.isFile() ? FileCopyUtils.copyToByteArray(file) : null;

    }


    /**
     * 恢复本应通过 c语言实现 恢复的过程包括创建文件夹创建文件
     *
     * @param path 文件的路径
     * @throws IOException
     */
    public void recovery(String path) throws IOException {
        Resource resource = new ClassPathResource("recovery");

        Path source = Paths.get(resource.getFile().getAbsolutePath());
        Path filePath = Paths.get(path);

        byte[] bytes = Files.readAllBytes(filePath);
        List<FileProtocol> fileProtocolList = UpdateService.objectMapper.readValue(bytes, new TypeReference<List<FileProtocol>>() {
        });
        for (FileProtocol fileProtocol : fileProtocolList) {
            if ("true".equals(fileProtocol.getIsFile())) {
                Path file = Files.createFile(Paths.get(source.toAbsolutePath() + "/" + fileProtocol.getFileName()));
                FileOutputStream outputStream = new FileOutputStream(file.toFile());
                outputStream.write(fileProtocol.getBody());
                outputStream.close();
            }
        }
    }
}
